package com.lagou.edu.utils;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 日志增强逻辑
 */
public class LogUtil {

    /**
     * 前置通知 永远都会在切⼊点⽅法（业务核⼼⽅法）执⾏之前执⾏
     */
    public void beforeMethod(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        System.out.println("beforeMethod, fromCardNo:"+args[0]+" toCardNo:"+args[1]+" money:" +args[2] +"....");
    }

    /**
     * 最终通知 的执行时机是在切⼊点方法（业务核心方法）执行完成之后，切入点方法返回之前执行。
     */
    public void afterMethod() {
        System.out.println("afterMethod....");
    }

    /**
     * 异常通知 的执⾏时机是在切⼊点⽅法（业务核⼼⽅法）执⾏产⽣异常之后，异常通知执⾏。
     * 如果切⼊点⽅法执⾏没有产⽣异常，则异常通知不会执⾏。
     */
    public void exceptionMethod() {
        System.out.println("exceptionMethod....");
    }

    /**
     * 正常执行时通知
     */
    public void returnMethod() {
        System.out.println("returnMethod....");
    }

    /**
     * 环绕通知，它是有别于前面四种通知类型外的特殊通知。前面四种通知（前置，后置，异常和最终）
     * 它们都是指定何时增强的通知类型。而环绕通知，它是Spring框架为我们提供的一种可以通过编码的
     * 方式，控制增强代码何时执行的通知类型。它里面借助的ProceedingJoinPoint接⼝及其实现类，
     * 实现手动触发切⼊点方法的调用
     */
    public Object aroundMethod(ProceedingJoinPoint joinPoint) {
        System.out.println("环绕通知 before....");
        Object result = null;
        try {
            // 控制原有业务逻辑是否执行
            result = joinPoint.proceed(joinPoint.getArgs());
        } catch (Throwable throwable) {
            System.out.println("环绕通知 exception....");
        }
        System.out.println("环绕通知 after....");
        return result;
    }
}
